#ifndef RMD_LANE_FEATURE_H_
#define RMD_LANE_FEATURE_H_

#include <cmath>
#include "data_frame.h"
#include "lane_const_parameter.h"

namespace rmd {

struct RoiBorder {
  int lcol;
  int rcol;
};

struct UdPair {
  cv::Point up_point;
  cv::Point down_point;
};

class LaneFeatureExtraction {
 private:
  DataFrame* data_frame_;

  cv::Mat pm_gray_image;
  cv::Mat pm_black_out_;
  cv::Mat lane_feature_show;

  std::vector<LaneResult> detect_line;

  short end_line_;
  short middle_start_line;
  short far_line_;
  short start_line;

  float extend_wid;

  std::vector<int> line_list_;
  cv::Point boundary_list_[5];
  std::vector<cv::Point2f> lane_width_limit;

  float threshold_value[kMaxChar];

  void GetThresholdValue();
  void SetDataFrameToClass(DataFrame* data_frame, cv::Mat& pm_black_out);
  void DetectUpdownLane(std::vector<uchar>& colors,
                        std::vector<UdPair>& ud_pair, int current_r,
                        int start_c);
  void FindMaxUpDown(std::vector<uchar>& colors, std::vector<bool>& up_point,
                     std::vector<bool>& down_point);
  void Neighbourvalue(std::vector<uchar>& colors, int start, int len,
                      float& diff, int& mean);
  void FindLaneUDpair(std::vector<bool>& up_p, std::vector<bool>& down_p,
                      std::vector<uchar>& colors, std::vector<UdPair>& ud_pair,
                      int current_p, int start_p);
  void DetectUdROILane(std::vector<UdPair>& pPair, int frow, int lrow);
  RoiBorder PointToBorder(cv::Point lp_pos);

 public:
  LaneFeatureExtraction();
  virtual ~LaneFeatureExtraction();

  void Update(DataFrame* data_frame, cv::Mat& pm_black_out);
};
}

#endif
